package com.candy.candycommon.config;

import com.candy.candycommon.annotation.CheckToken;
import com.candy.candycommon.enums.AppEnum;
import com.candy.candycommon.exception.BusinessException;
import com.candy.candycommon.utils.WebUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * Web切面配置
 *
 * @author syl
 */
@Slf4j
@Aspect
@Configuration
public class WebAspect {

    public static final String SESSION_TOKEN = "token";

    /**
     * 定义切入点（切入点为Spring的Controller注解）
     */
    @Pointcut("@within(org.springframework.stereotype.Controller) || @within(org.springframework.web.bind.annotation.RestController)")
    public void pointCut() {
    }

    /**
     * @description 在切入点执行之前执行的通知
     */
    @Before("pointCut()")
    public void doBefore() {
        log.debug("Point Before");
    }

    /**
     * @description 在切入点执行之后执行的通知（返回通知和异常通知的异常）
     */
    @After("pointCut()")
    public void doAfter() {
        log.debug("Point After");
    }

    /**
     * @description 在切入点执行之后执行的通知（返回通知）
     */
    @AfterReturning("pointCut()")
    public void doAfterReturning() {
        log.debug("Point AfterReturning");
    }

    /**
     * @description 在切入点执行之后执行的通知（异常通知）
     */
    @AfterThrowing("pointCut()")
    public void doAfterThrowing() {
        log.debug("Point AfterThrowing");
    }

    @Around("pointCut()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        Object result = null;
        try {
            log.debug("Point Around Start");
            log.debug("权限处理");
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            Object[] arg = joinPoint.getArgs();
            MethodSignature ms = (MethodSignature) joinPoint.getSignature();
            CheckToken checkTokenClass = ms.getMethod().getDeclaringClass().getAnnotation(CheckToken.class);
            CheckToken checkTokenMethod = ms.getMethod().getAnnotation(CheckToken.class);
            if (checkTokenClass != null || checkTokenMethod != null) {
                AppEnum appEnum = checkTokenClass.value();
                // appEnum 校验渠道

                String token = request.getHeader(SESSION_TOKEN);
                // checkToken(token)
                Object object = new Object();
                if (object == null) {
                    throw new BusinessException("");
                } else {
                    WebUtil.add(object);
                }
            }
            result = joinPoint.proceed(arg);
        } catch (BusinessException e) {
            log.error("异常", e);
            result = new Object();
        } finally {
            log.debug("Point Around End");
            WebUtil.clear();
        }
        return result;
    }

}
